package org.codehaus.activemq.transport.tcp;

import EDU.oswego.cs.dl.util.concurrent.Executor;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URI;
import javax.jms.JMSException;
import javax.net.SocketFactory;
import org.codehaus.activemq.message.WireFormat;
import org.codehaus.activemq.transport.TransportChannel;

public class SfTransportChannelFactory extends TcpTransportChannelFactory
{
  private SocketFactory socketFactory;
  private Executor executor;

  public SfTransportChannelFactory(SocketFactory socketFactory)
  {
    this.socketFactory = socketFactory;
  }

  public TransportChannel create(WireFormat wireFormat, URI remoteLocation)
    throws JMSException
  {
    Socket socket = null;
    try {
      socket = createSocket(remoteLocation);
    }
    catch (IOException e) {
      JMSException jmsEx = new JMSException("Creation of Socket failed: " + e);
      jmsEx.setLinkedException(e);
      throw jmsEx;
    }
    return new TcpTransportChannel(wireFormat, socket, this.executor);
  }

  public TransportChannel create(WireFormat wireFormat, URI remoteLocation, URI localLocation)
    throws JMSException
  {
    Socket socket = null;
    try {
      socket = createSocket(remoteLocation, localLocation);
    }
    catch (IOException e) {
      JMSException jmsEx = new JMSException("Creation of Socket failed: " + e);
      jmsEx.setLinkedException(e);
      throw jmsEx;
    }
    return new TcpTransportChannel(wireFormat, socket, this.executor);
  }

  protected Socket createSocket(URI remoteLocation) throws IOException {
    return this.socketFactory.createSocket(remoteLocation.getHost(), remoteLocation.getPort());
  }

  protected Socket createSocket(URI remoteLocation, URI localLocation) throws IOException {
    return this.socketFactory.createSocket(remoteLocation.getHost(), remoteLocation.getPort(), InetAddress.getByName(localLocation.getHost()), localLocation.getPort());
  }
}